<?php
/**
 * OrangeHRM is a comprehensive Human Resource Management (HRM) System that captures
 * all the essential functionalities required for any enterprise.
 * Copyright (C) 2006 OrangeHRM Inc., http://www.orangehrm.com
 *
 * OrangeHRM is free software; you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * OrangeHRM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA
 *
 */

require_once ROOT_PATH . '/lib/dao/DMLFunctions.php';
require_once ROOT_PATH . '/lib/dao/SQLQBuilder.php';
require_once ROOT_PATH . '/lib/models/leave/LeaveType.php';
require_once ROOT_PATH . '/lib/common/Config.php';

require_once ROOT_PATH . '/lib/models/hrfunct/EmpInfo.php';
class LeaveQuota {

	/**
	 * Class constants
	 */
	const LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA = "hs_hr_employee_leave_quota";

	const LEAVEQUOTA_DB_FIELD_YEAR = "year";
	const LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID = "leave_type_id";
	const LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID = "employee_id";
	const LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED = "no_of_days_allotted";
	const LEAVEQUOTA_DB_FIELD_LEAVE_TAKEN = "leave_taken";
	const LEAVEQUOTA_DB_FIELD_LEAVE_BROUGHT_FORWARD = "leave_brought_forward";
        const LEAVEQUOTA_DB_FIELD_UPDATED_AT = "updated_at";        
        const LEAVEQUOTA_DB_FIELD_ID = "id";

	const LEAVEQUOTA_CRITERIA_ALL = 0;

	/**
	 *	Class atributes
	 */
        private $id;
	private $year;
	private $leaveTypeId;
	private $employeeId;
	private $noOfDaysAllotted;
        private $updatedAt;
	private $leaveTypeName;
	private $errorMessage;

	/**
	 *
	 *	Class contructor
	 */
	public function __construct() {
		//nothing to do
	}

	/**
	 *	Getter method followed by setter method for each
	 *	attribute
	 */
        public function getId() {
		return $this->id;
	}

	public function setId($id) {
		$this->id = $id;
	}
        
	public function getYear() {
		return $this->year;
	}

	public function setYear($year) {
		$this->year = $year;
	}

	public function getLeaveTypeId() {
		return $this->leaveTypeId;
	}

	public function setLeaveTypeId($leaveTypeId) {
		$this->leaveTypeId = $leaveTypeId;
	}

	public function getEmployeeId() {
		return $this->employeeId;
	}

	public function setEmployeeId($employeeId) {
		$this->employeeId = $employeeId;
	}

	public function getNoOfDaysAllotted() {
		return $this->noOfDaysAllotted;
	}

	public function setNoOfDaysAllotted($noOfDaysAlotted) {
		$this->noOfDaysAllotted = $noOfDaysAlotted;
	}

	public function getLeaveTypeName() {
		return $this->leaveTypeName;
	}

	public function setLeaveTypeName($leaveTypeName) {
		$this->leaveTypeName = $leaveTypeName;
	}

	public function getErrorMessage() {
		return $this->errorMessage;
	}

	public function setErrorMessage($errorMessage) {
		$this->errorMessage = $errorMessage;
	}

        public function getUpdatedAt() {
		return $this->updatedAt;
	}

	public function setUpdatedAt($date) {
		$this->updatedAt = $date;
	}	

	/**
	 * Add Leave Quota of an employee
	 *
	 * @param String $employeeId
	 * @return boolean
	 * @access public
	 */
	public function addLeaveQuota($employeeId) {

		$this->setEmployeeId($employeeId);

		$sqlBuilder = new SQLQBuilder();

		$insertTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";

		$insertFields[0] = "`".self::LEAVEQUOTA_DB_FIELD_YEAR."`";
		$insertFields[1] = "`".self::LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID."`";
		$insertFields[2] = "`".self::LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID."`";
		$insertFields[3] = "`".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED."`";
                $insertFields[4] = "`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";

		$insertValues[0] = "'" . $this->getYear() . "'";
		$insertValues[1] = "'" . $this->getLeaveTypeId() . "'";
		$insertValues[2] = "'" . $this->getEmployeeId() . "'";
                if($this->getLeaveTypeId()!= "LTY001")
                    $insertValues[3] = $this->getNoOfDaysAllotted();
		else
                    $insertValues[3] = $this->setLeaveDaysAllotted($employeeId,$this->getYear());
                $insertValues[4] = date('Y-m-d');
		$query = $sqlBuilder->simpleInsert($insertTable, $insertValues, $insertFields);

		$dbConnection = new DMLFunctions();
		$result = $dbConnection->executeQuery($query);

		if ($result) {
			return true;
		}

		return false;
	}
	/*
	 * Chinh Nguyen add
	 *  
	*/
	//get work time by  months, return Days allotted of the employee have empid = $empID	
	
	function setLeaveDaysAllotted($empID, $year_end) {
            $employee = new EmpInfo();
            $employeeJob = $employee->filterEmpJobInfo($empID);
            //Get joined day of the employee
            $leaveAllotted = 0;
            if (!empty($employeeJob)) {
                $joined_date = empty($employeeJob[0][5]) ? 0 : $employeeJob[0][5];
                if ($joined_date == 0) {
                    $joined_time = mktime();
                } else {
                    list($year, $month, $day) = split("-", $joined_date);
                    $joined_time = mktime(0, 0, 0, $month, $day, $year);
                }
                //Current time	
                $now = mktime();

                // Calculate leave day(s) allotted of employee follow S3 rules	
                $leaveAllotted = $this->calcMonthDiff($joined_time, $now, $empID, $year_end);
            }

            return $leaveAllotted;
        }	
	
	//caculate number of day allotted between 2 date	
        public function calcMonthDiff($ts_start, $ts_end, $empID, $year_end) {

            //error protection
            if ($ts_start > $ts_end)
                return false;

            $diff = 0;
            // Get time start
            $month_start = intval(date('m', $ts_start));            
            $year_start = intval(date('Y', $ts_start));
            //Get time end
            $month_end = intval(date('m', $ts_end));            
            $year_curr = intval(date('Y', $ts_end));

            $leaveObj = new LeaveSummary();

            if ($year_curr == $year_end) {                		
                if ($year_end < $year_start) {
                    $diff = 0;
                } elseif ($year_end == $year_start) {
                    $diff = $month_end - $month_start;
                } else {
                    $lastRemain = $leaveObj->getLeaveRemain($empID, $year_end - 1, 'LTY001');
                    if ($lastRemain > 12) {
                        $diff = 12 + $month_end;
                    } else {
                        $diff = $lastRemain + $month_end;
                    }
                }
            } else {
                if ($year_end < $year_start) {
                    $diff = 0;
                } elseif ($year_end == $year_start) {
                    $diff = 12 - $month_start;
                } else {
                    $lastRemain = $leaveObj->getLeaveRemain($empID, $year_end - 1, 'LTY001');
                    if ($lastRemain > 12) {
                        $diff = 24;
                    } else {
                        $diff = 12 + $lastRemain;
                    }
                }
            }

            if ($diff < 0)
                $diff = 0;

            return $diff;
        }
        

	public function editLeaveQuota() {
		if ($this->checkRecordExsist()) {
			return $this->updateLeaveQuota();
		}
		return $this->addLeaveQuota($this->getEmployeeId());
	}


	public function updateLeaveQuota() {
		$sqlBuilder = new SQLQBuilder();

		$updateTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";

		$updateFileds[0] = "`".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED."`";               
		if($this->getLeaveTypeId() != "LTY001")
		{
			$updateValues[0] = "'" . $this->getNoOfDaysAllotted() . "'";
                        if(is_null($this->getUpdatedAt())){
                            $updateFileds[1] = "`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";
                            $updateValues[1] = date('Y-m-d');
                        }
		}
		else{                    
                    $daysAllotted = $this->setLeaveDaysAllotted($this->getEmployeeId(),$this->getYear());
                    $updateValues[0] = $daysAllotted;
                    if($this->getNoOfDaysAllotted() != 'x' ){
                        $updateFileds[1] = "`".self::LEAVEQUOTA_DB_FIELD_LEAVE_BROUGHT_FORWARD."`";
                        $updateValues[1] = $this->getNoOfDaysAllotted() -  $daysAllotted;
                        //$updateFileds[2] = "`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";
                        //$updateValues[2] = date('Y-m-d');
                    } 
		}
                $updateConditions[0] = "`".self::LEAVEQUOTA_DB_FIELD_ID."` = '".$this->getId()."'";		
		
		$query = $sqlBuilder->simpleUpdate($updateTable, $updateFileds, $updateValues, $updateConditions);
                    
		$dbConnection = new DMLFunctions();                
		$result = $dbConnection->executeQuery($query);

		if ($result) {
			return true;
		}
		return false;
	}

	
        private function checkRecordExsist() {
		$sqlBuilder = new SQLQBuilder();
		$selectTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";
		$selectFields[0] = "COUNT(*)";
		$selectConditions[0] = "`".self::LEAVEQUOTA_DB_FIELD_ID."` = '".$this->getId()."'";		
		$query = $sqlBuilder->simpleSelect($selectTable, $selectFields, $selectConditions);
		$dbConnection = new DMLFunctions();
		$result = $dbConnection->executeQuery($query);
		$count = mysql_fetch_row($result);
		if ($count[0] > 0) {
			return true;
		}
		return false;
	}
        
        public static function getQuotaById($id) {
		$sqlBuilder = new SQLQBuilder();
		$selectTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";
                $arrFields[0] = "`".self::LEAVEQUOTA_DB_FIELD_ID."`";
		$arrFields[1] = "`".self::LEAVEQUOTA_DB_FIELD_YEAR."`";
		$arrFields[2] = "`".self::LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID."`";		
		$arrFields[3] = "`".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED."`";
		$arrFields[4] = "`".self::LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID."`";                
                $arrFields[5] = "`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";
		$selectConditions[0] = "`".self::LEAVEQUOTA_DB_FIELD_ID."` = '".$id."'";		
		$query = $sqlBuilder->simpleSelect($selectTable, $arrFields, $selectConditions);
		$dbConnection = new DMLFunctions();
		$result = $dbConnection->executeQuery($query);
                $leaveQuota = new LeaveQuota();
                while ($row = mysql_fetch_row($result)) {
                        $leaveQuota->setId($row[0]);
			$leaveQuota->setYear($row[1]);
			$leaveQuota->setLeaveTypeId($row[2]);			
			$leaveQuota->setNoOfDaysAllotted($row[3]);
                        $leaveQuota->setEmployeeId($row[4]);
                        $leaveQuota->setUpdatedAt($row[5]);
		}                
		return $leaveQuota;
	}

	/**
	 *	Add Default Leave Quota Details For Leave
	 *	available to the employee.
	 *
	 * 	@return  true
	 * 	@access public
	 */

	 public function addLeaveQuotaAdmin(){

     	if (!$this->checkAnnualRecordExsist()) {
        	if($this->addLeaveQuota($this->getEmployeeId())) return true ;
            else return false ;
        }

        return true ;
	}


	public function fetchLeaveQuota($employeeId) {
		$sqlBuilder = new SQLQBuilder();

		$arrFields[0] = "a.`".self::LEAVEQUOTA_DB_FIELD_YEAR."`";
		$arrFields[1] = "a.`".self::LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID."`";
		$arrFields[2] = "b.`leave_type_name`";
		$arrFields[3] = "a.`".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED."`";
		$arrFields[4] = "a.`".self::LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID."`";
                $arrFields[5] = "a.`".self::LEAVEQUOTA_DB_FIELD_ID."`";
                $arrFields[6] = "a.`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";

		$arrTables[0] = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."` a";
		$arrTables[1] = "`hs_hr_leavetype` b";

		$joinConditions[1] = "a.`".self::LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID."` = b.`leave_type_id`";

		$selectConditions = null;

		$selectOrderBy = $arrFields[4];

		if ($this->getYear() != null) {
			$selectConditions[] = "a.`".self::LEAVEQUOTA_DB_FIELD_YEAR."` = '{$this->getYear()}'";
		}

		if ($employeeId != 0) {
			$selectConditions[] = "a.`".self::LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID."` = '" . $employeeId . "'";
			$selectOrderBy = $arrFields[1];
		}

		$selectConditions[] = "a.`".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED."` > 0";

		$joinTypes[1] = "LEFT";

		$selectOrderBy="$arrFields[0], $selectOrderBy";
		$selectOrder = "DESC";

		$query = $sqlBuilder->selectFromMultipleTable($arrFields, $arrTables, $joinConditions, $selectConditions, $joinTypes, $selectOrderBy, $selectOrder);

		$dbConnection = new DMLFunctions();

		$result = $dbConnection->executeQuery($query);

		$leaveTypeArr = $this->_buildObjArr($result);

		return $leaveTypeArr;
	}

	public function checkBroughtForward ($year) {

		$sqlBuilder = new SQLQBuilder();

		$selectTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";

		$selectFields[0] = "SUM(".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED.")";

		$selectConditions[0] = "`".self::LEAVEQUOTA_DB_FIELD_YEAR."` = '".$year."'";

		$query = $sqlBuilder->simpleSelect($selectTable, $selectFields, $selectConditions);

		$dbConnection = new DMLFunctions();

		$result = $dbConnection->executeQuery($query);

		$row = $dbConnection->dbObject->getArray($result);

		if ($row['SUM(no_of_days_allotted)'] > 0) {
			return true;
		} else {
			return false;
		}

	}

	public function isLeaveQuotaDeleted() {

		$leaveTypeObj = new LeaveType();
		$leaveType = $leaveTypeObj->retriveLeaveType($this->leaveTypeId);

		return (($leaveType[0]->getLeaveTypeAvailable() == $leaveType[0]->availableStatusFlag) ? false : true);
	}

	protected function _buildObjArr($result) {

		$objArr = null;

		while ($row = mysql_fetch_row($result)) {

			$tmpLeaveArr = new LeaveQuota();

			$tmpLeaveArr->setYear($row[0]);
			$tmpLeaveArr->setLeaveTypeId($row[1]);
			$tmpLeaveArr->setLeaveTypeName($row[2]);
			$tmpLeaveArr->setNoOfDaysAllotted($row[3]);

			$objArr[] = $tmpLeaveArr;
		}

		return $objArr;
	}
        
        
        //Annual leave process
        public function editAnnualLeaveQuota() {
		if ($this->checkAnnualRecordExsist()) {
			return $this->updateAnnualLeaveQuota();
		}
		return $this->addLeaveQuota($this->getEmployeeId());
	}
        
        public function updateAnnualLeave($year,$empNumber = null){
		if(is_null($empNumber)){
			$empInfoObj = new EmpInfo();
			$array = $empInfoObj->getListofEmployee();
			for($i=0; $i< count($array);$i++){
		       	$quoObj = new LeaveQuota();
				$quoObj->setYear($year);
				$quoObj->setEmployeeId($array[$i][2]);
				$quoObj->setLeaveTypeId('LTY001');
				$quoObj->setNoOfDaysAllotted(0);
				$quoObj->editAnnualLeaveQuota();
			}
		}else{
			$quoObj = new LeaveQuota();
			$quoObj->setYear($year);
			$quoObj->setEmployeeId($empNumber);
			$quoObj->setLeaveTypeId('LTY001');
			$quoObj->setNoOfDaysAllotted('x');
			$quoObj->editAnnualLeaveQuota();
		}
	}
        
        public function updateAnnualLeaveQuota() {
		$sqlBuilder = new SQLQBuilder();

		$updateTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";

		$updateFileds[0] = "`".self::LEAVEQUOTA_DB_FIELD_NO_OF_DAYS_ALLOTED."`";
                
		if($this->getLeaveTypeId() != "LTY001")
		{
			$updateValues[0] = "'" . $this->getNoOfDaysAllotted() . "'";
                        $updateFileds[1] = "`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";
                        $updateValues[1] = date('Y-m-d');
		}
		else{                    
                    $daysAllotted = $this->setLeaveDaysAllotted($this->getEmployeeId(),$this->getYear());
                    $updateValues[0] = $daysAllotted;
                    if($this->getNoOfDaysAllotted() != 'x' ){
                        $updateFileds[1] = "`".self::LEAVEQUOTA_DB_FIELD_LEAVE_BROUGHT_FORWARD."`";
                        $updateValues[1] = $this->getNoOfDaysAllotted() -  $daysAllotted;
                        $updateFileds[2] = "`".self::LEAVEQUOTA_DB_FIELD_UPDATED_AT."`";
                        $updateValues[2] = date('Y-m-d');
                    } 
		}
		$updateConditions[0] = "`".self::LEAVEQUOTA_DB_FIELD_YEAR."` = '".$this->getYear()."'";
		$updateConditions[1] = "`".self::LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID."` = '".$this->getLeaveTypeId()."'";
		$updateConditions[2] = "`".self::LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID."` = '".$this->getEmployeeId()."'";
		
		$query = $sqlBuilder->simpleUpdate($updateTable, $updateFileds, $updateValues, $updateConditions);
                    
		$dbConnection = new DMLFunctions();

		$result = $dbConnection->executeQuery($query);

		if ($result) {
			return true;
		}
		return false;
	}
        
        private function checkAnnualRecordExsist() {
		$sqlBuilder = new SQLQBuilder();

		$selectTable = "`".self::LEAVEQUOTA_DB_TABLE_EMPLOYEE_LEAVE_QUOTA."`";

		$selectFields[0] = "COUNT(*)";

		$selectConditions[0] = "`".self::LEAVEQUOTA_DB_FIELD_YEAR."` = '".$this->getYear()."'";
		$selectConditions[1] = "`".self::LEAVEQUOTA_DB_FIELD_LEAVE_TYPE_ID."` = '".$this->getLeaveTypeId()."'";
		$selectConditions[2] = "`".self::LEAVEQUOTA_DB_FIELD_EMPLOYEE_ID."` = '".$this->getEmployeeId()."'";

		$query = $sqlBuilder->simpleSelect($selectTable, $selectFields, $selectConditions);

		$dbConnection = new DMLFunctions();

		$result = $dbConnection->executeQuery($query);

		$count = mysql_fetch_row($result);

		if ($count[0] > 0) {
			return true;
		}

		return false;
	}
}

class LeaveQuotaException extends Exception {
	const ERROR_IN_DB_QUERY = 1;
	const CANNOT_CARRY_LEAVE_FORWARD_YEAR_IN_THE_FUTURE = 2;
	const CANNOT_CARRY_LEAVE_FORWARD_NON_CONSECUTIVE_YEARS = 3;
	const CANNOT_CARRY_LEAVE_FORWARD_YEAR_NOT_OVER = 4;
	const NOTHING_TO_UPDATE = 5;
}
?>
